'''

@SDK功能描述：鼠标轨迹

'''
from ctypes import cdll, Structure, c_int, c_char, c_char_p, POINTER, create_string_buffer
import ctypes
import os
import sys

# 创建句柄
key = "SNKJ86RYDBY1YxafpLG3ep1R6NHFYLjz2UFFcE8Lx9Tq"  # 字符串
key_bytes = key.encode('utf-8')  # 将字符串转换为 bytes

# 设置模型文件路径
onnx = "d://SNTrack.onnx"  # 字符串
onnx_bytes = onnx.encode('utf-8')  # 将字符串转换为 bytes

# 假设 DLL 文件名为 SNSDK.dll
sn_sdk = ctypes.WinDLL('d://SNSDK.dll')


# 定义 SN_RESULT 结构体
class SN_RESULT(ctypes.Structure):
    _fields_ = [("code", ctypes.c_int),
                ("message", ctypes.c_char * 4096)]


# 定义 SN_POINT 结构体
class SN_POINT(ctypes.Structure):
    _fields_ = [("x", ctypes.c_int),
                ("y", ctypes.c_int)]


# 定义 SN_POINT_PARAMS 结构体
class SN_POINT_PARAMS(ctypes.Structure):
    _fields_ = [("point", SN_POINT),
                ("delayTime", ctypes.c_int)]


# 定义函数原型
sn_sdk.apiSNCreateHandle.argtypes = [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_char),
                                     ctypes.POINTER(SN_RESULT)]
sn_sdk.apiSNCreateHandle.restype = ctypes.c_void_p

sn_sdk.apiSNGetVersion.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_char)]
sn_sdk.apiSNGetVersion.restype = ctypes.c_int

sn_sdk.apiSNSetTrackParams.argtypes = [ctypes.c_void_p, ctypes.c_int,ctypes.c_int]
sn_sdk.apiSNSetTrackParams.restype = ctypes.c_int

sn_sdk.apiSNGetKeyExpiresTime.argtypes = [ctypes.c_void_p, ctypes.POINTER(SN_RESULT)]
sn_sdk.apiSNGetKeyExpiresTime.restype = c_char_p


sn_sdk.apiSNMouseMove.argtypes = [ctypes.c_void_p, POINTER(SN_POINT), POINTER(SN_POINT), ctypes.c_int, ctypes.POINTER(SN_POINT_PARAMS)]
sn_sdk.apiSNMouseMove.restype = ctypes.c_int  # 根据实际情况调整

sn_sdk.apiSNDestroyHandle.argtypes = [ctypes.c_void_p]
sn_sdk.apiSNDestroyHandle.restype = ctypes.c_int

result = SN_RESULT()  # 创建 SN_RESULT 实例
handle = sn_sdk.apiSNCreateHandle(key_bytes, onnx_bytes, ctypes.byref(result))
if result.code != 0:
    message = result.message.decode('gbk', errors='replace').strip()
    print("Result message:", message)
else:
    print("Handle created successfully")

# 获取版本号
version = ctypes.create_string_buffer(4096)
version_result = sn_sdk.apiSNGetVersion(handle, version)
if version_result != 0:
    print("Result message:", version_result)
else:
    message = result.message.decode('gbk', errors='replace').strip()
    print("Result message:", version.value.decode())


# 获取卡密到期时间
print("key 到期时间:", sn_sdk.apiSNGetKeyExpiresTime(handle, ctypes.byref(result)))

'''
设置轨迹参数，轨迹密度density调节，默认5倍速，根据自身需求设置 ,density必须大于或者等于 1，默认 5,
举个例子：假如轨迹有 100 个点，累计耗时 1000 毫秒，设置 density 如下：
				-  density = 1  时，轨迹有 100/1=100 个点，整个轨迹累计耗时 1000/1=1000 毫秒 （默认 1  倍速度）
				-  density = 2  时，轨迹有 100/2=50  个点，整个轨迹累计耗时 1000/2=500  豪秒 （等价 2  倍速度）
				-  density = 3  时，轨迹有 100/3=33  个点，整个轨迹累计耗时 1000/3=333  豪秒 （等价 3  倍速度）
				-  density = 5  时，轨迹有 100/5=20  个点，整个轨迹累计耗时 1000/5=200  豪秒 （等价 5  倍速度）
				-  density = 20 时，轨迹有 100/20=5  个点，整个轨迹累计耗时 1000/20=50  豪秒 （等价 20 倍速度）
	
'''

sn_sdk.apiSNSetTrackParams(handle, 5, 0)# 默认5倍速，如果不调节速度/密度的情况下可以不调用


# 获取轨迹
# 定义开始和结束坐标
start_point = SN_POINT(100, 100)
end_point = SN_POINT(800, 800)

# 轨迹类型： 0 表示绝对坐标   1 表示相对坐标  其他值返回错误
type = 0

# 假设返回的轨迹点数量
num_points = 4096

# 创建一个数组来接收轨迹点
points_array = (SN_POINT_PARAMS * num_points)()

# 调用 apiSNMouseMove 函数
move_result_code = sn_sdk.apiSNMouseMove(handle, start_point, end_point, type, points_array)

# 检查结果
if move_result_code != 0:
    print("apiSNMouseMove error code:", move_result_code)
else:
    # 遍历并打印每个点
    for i in range(num_points):

        # 判断是否轨迹是否结束（x 和 Y 都是 10000 时，轨迹结束）
        if points_array[i].point.x == 10000 and points_array[i].point.y == 10000:
            break  # 轨迹结束
        print(
            f"Point {i}: ({points_array[i].point.x}, {points_array[i].point.y},{points_array[i].delayTime})")  # X坐标 ,Y坐标 ,延时时间

# 释放句柄
destroy_result_code = sn_sdk.apiSNDestroyHandle(handle)
if destroy_result_code != 0:
    print("apiSNDestroyHandle error code:", destroy_result_code)
else:
    print("Handle destroyed successfully")

